package com.game.modular.game.playerAssets.service.base;

import com.game.modular.gameCore.cultivate.domain.CoreProp;
import com.game.modular.gameCore.cultivate.service.impl.CorePropServiceImpl;
import lombok.extern.slf4j.Slf4j;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.game.modular.game.playerAssets.mapper.PlayerBagMapper;
import com.game.modular.game.playerAssets.domain.PlayerBag;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;

/**
 * 基础服务-背包物品
 *
 * @author cxy
 * @since 2024-09-10 18:33:11
 */
@Slf4j
@Service
public class PlayerBagBaseServiceImpl extends ServiceImpl<PlayerBagMapper, PlayerBag> {
    private static final String cacheKey = "player:%d:bag";
    @Resource
    private RedisTemplate<Object, Object> redisTemplate;
    @Resource
    private ValueOperations<Object, PlayerBag> valueOperations;
    @Resource
    private HashOperations<Object, Object, PlayerBag> hashOperations;
    @Resource
    private CorePropServiceImpl corePropServiceImpl;
    @Resource
    private PlayerBagMapper playerBagMapper;


    ///////////////////////////////////////////////////////////////////////////////////////////////////////////  基础查询
    public List<PlayerBag> eqlist(
            @NotNull(message = "select不能为空") PlayerBag select
    ) {
        Long uid = select.getUid();
        if (uid == null){
            throw new RuntimeException("uid不能为空");
        }
        List<PlayerBag> list = listCache(uid).stream()
                .filter(item -> {
                    boolean isMatch = false;
                    Long corePropId = select.getCorePropId();
                    if (corePropId != null) {
                        isMatch = item.getCorePropId().equals(corePropId);
                    }
                    Long id = select.getId();
                    if (id != null) {
                        isMatch = item.getId().equals(id);
                    }
                    return isMatch;
                })
                .collect(Collectors.toList());
        if (list.isEmpty()) {
            list = super.list(new LambdaQueryWrapper<>(select));
            savaCache(uid,listToMap(list));
            return list;
        }
        return list;
    }
    public PlayerBag eqSelect(
            @NotNull(message = "select不能为空") PlayerBag select
    ) {
        return eqlist(select).stream().findFirst().orElse(null);
    }
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////    转换
    public Map<String, PlayerBag> listToMap(List<PlayerBag> list) {
        return list.stream().collect(Collectors.toMap(
                k -> k.getId().toString(),
                v -> v
        ));
    }
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////  更新插入
    @Override
    public boolean updateById(PlayerBag entity) {
        boolean b = super.updateById(entity);
        savaCache(entity);
        return b;
    }

    @Override
    public boolean save(PlayerBag entity) {
        boolean save = super.save(entity);
        if (entity.getStack()==null){
            CoreProp cache = corePropServiceImpl.getCache(entity.getCorePropId());
            entity.setStack(cache.getStack());
        }
        savaCache(entity);
        return save;
    }

    @Override
    public boolean removeById(Serializable id) {
        PlayerBag byId = super.getById(id);
        removeCache(byId);
        return super.removeById(id);
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////  缓存部分
    public void savaCache(Long uid, Map<String, PlayerBag> map) {
        String key1 = String.format(cacheKey, uid);
        hashOperations.putAll(key1, map);
    }

    public void savaCache(PlayerBag entity) {
        String key1 = String.format(cacheKey, entity.getUid());
        String key2 = entity.getId().toString();
        hashOperations.put(key1, key2, entity);
        redisTemplate.expire(key1, 60, TimeUnit.MINUTES);
    }

    public PlayerBag selectCache(
            @NotNull(message = "keyValue1不能为空") Long uid,
            @NotNull(message = "keyValue2不能为空") Long id
    ) {
        String key1 = String.format(cacheKey, uid);
        String key2 = id.toString();
        redisTemplate.expire(key1, 60, TimeUnit.MINUTES);
        return hashOperations.get(key1, key2);
    }

    public List<PlayerBag> listCache(
            @NotNull(message = "keyValue1不能为空") Long uid
    ) {
        String key1 = String.format(cacheKey, uid);
        redisTemplate.expire(key1, 60, TimeUnit.MINUTES);
        return new ArrayList<>(hashOperations.entries(key1).values());
    }

    public void removeCache(PlayerBag entity) {
        String key1 = String.format(cacheKey, entity.getUid());
        String key2 = entity.getId().toString();
        hashOperations.delete(key1, key2);
    }
}
